<?php

Raise::load('core.RaiseObject');
Raise::load('db.core.RaiseDbConnection');
Raise::load('core.helper.convert.RaiseConvert');
Raise::load('core.RaiseTypedCollection');
Raise::load('db.core.RaiseDbTableColumn');
Raise::load('core.reflection.RaiseVariable');

/**
 * RaiseDbAdapter abstract class
 * templates a class that provides Data Access gateway between phpRaise Data Access
 * classes and generic functions/classes
 *
 * @author Sam-Mauris Yong / hellclanner at live dot com
 * @license http://www.opensource.org/licenses/bsd-license New BSD License
 * @abstract
 * @package phpraise.db.core
 * @since 1.2
 */
abstract class RaiseDbAdapter extends RaiseObject {

    /**
     * The connection
     * @var RaiseDbConnection
     */
    protected $connection;

    /**
     * The generic connection object/resource
     * @var resource|object
     */
    private $genericConnection;

    /**
     * The generate operation result object/resource
     * @var resource|object
     */
    private $result;

    /**
     * Get or set the connection to this adapter
     * @param RaiseDbConnection $c (optional) The new connection to set to
     * @return RaiseDbConnection
     */
    public function connection($c = null){
        if(func_num_args() == 1){
            if(!($c instanceof RaiseDbConnection)){
                throw new RaiseInvalidArgumentException('RaiseDbSqlIdentifier::connection() expecting parameter $c to an instance of RaiseDbConnection, ' . RaiseVariable::typeInfo($c) . ' given instead.');
            }
            $this->connection = $c;
        }
        return $this->connection;
    }

    /**
     * Get or set the underlying generic result
     * @param resource|object $r (optional) If set, the new value will be set
     * @return resource|object
     */
    public function result($r = null){
        if(func_num_args() == 1){
            $this->result = $r;
        }
        return $this->result;
    }

    /**
     * Get or set the underlying generic connection object/resource
     * @param resource|object $conn (optional) If set, the new value will be set
     * @return resource|object
     */
    public function genericConnection($conn = null){
        if(func_num_args() == 1){
            $this->genericConnection = $conn;
        }
        return $this->genericConnection;
    }

    /**
     * Determine if the adapter is connected.
     * @return boolean
     */
    public function isConnected(){
        return RaiseConvert::to(RaiseConvert::TO_BOOLEAN, $this->genericConnection());
    }

    /**
     * Connect to the Database server using DataAccessConnection
     */
    abstract function connect();

    /**
     * Disconnect from the to the Database Server
     * @return boolean
     */
    abstract function disconnect();

    /**
     * Get the last insert ID
     * @return integer
     */
    abstract function lastInsertId();

    /**
     * Escape a string for query use
     * @param string $s
     * @return string
     */
    abstract function escapeString($s);

    /**
     * Execute a query
     * @param string $q The query to execute
     */
    abstract function query($q);

    /**
     * Get the next row as array
     * @return RaiseCollection|boolean
     */
    abstract function fetchRowArray();

    /**
     * Get the next row as an class object
     * @param string $class The name of the class to return
     * @return object|boolean
     */
    abstract function fetchRowObject($class);

    /**
     * Enquote identifier names
     * @param string $name The name of the identifier to enquote
     * @return string
     */
    abstract function enquote($name);

    /**
     * Load the RaiseDbTableColumn collection that describes the table
     * @param string $table The name of the table to fetch from
     * @return RaiseTypedCollection
     */
    abstract function tableColumns($table);

    /**
     * Translate Database DataType into phpRaise / PHP DataType
     * @param string $dataType The datatype from the database e.g. int(11)
     * @return string The data type in phpRaise e.g. integer
     */
    abstract function translateDataType($dataType);
    
    /**
     * Get the number of rows affected by the last execution
     * @return integer
     */    
    abstract function rowsAffected();

    /**
     * Get the transaction command for starting a new transaction
     * @return string
     */
    abstract function transactBegin();

    /**
     * Get the transaction command for committing and closing the transaction
     * @return string
     */
    abstract function transactCommit();

    /**
     * Get the transaction command for reverting changes and closing transaction
     * @return string
     */
    abstract function transactRollback();

    /*
     * Get the last error message
     * @return string
     */
    abstract function lastError();

    /**
     * Return the adapter identifier
     * @return string
     * @ignore
     */
    function __toString(){
        return 'generic';
    }

}
